/*

Modified from Microsoft/Sora on Github.

Original license:



Microsoft Research Software Radio

Copyright (c) Microsoft Corporation

All rights reserved.

BSD License

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifdef __GNUC__

#pragma once

#ifndef __ARM_NEON__
#include <emmintrin.h>
#else
#include "neon/vector128.h"
//#include "neon/sse_to_neon.h"
#define A16 __attribute__ ((aligned(16)))
#endif
#include "numerics.h"

#ifndef __ARM_NEON__
/* replicate 16 254 */
extern const __m128i ALL_INVERSE_ONE =
  _mm_set_epi8 ( 0xFE, 0xFE, 0xFE, 0xFE,
                 0xFE, 0xFE, 0xFE, 0xFE,
                 0xFE, 0xFE, 0xFE, 0xFE,
                 0xFE, 0xFE, 0xFE, 0xFE );

/* replicate 16 1 */
extern const __m128i ALL_ONE =
  _mm_set_epi8 ( 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 );

/* replicate 16 128 */
extern const __m128i ALL_M128 =
  _mm_set_epi8 ( 0x80, 0x80, 0x80, 0x80,
                 0x80, 0x80, 0x80, 0x80,
                 0x80, 0x80, 0x80, 0x80,
                 0x80, 0x80, 0x80, 0x80 );

/* replicate 16 48 */
extern const __m128i ALL_INIT =
  _mm_set_epi8 ( 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
                 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 );

/* replicate 16 48 */
extern const __m128i ALL_INIT0 =
  _mm_set_epi8( 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
                0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00 );

/* [0,4..252] */
calign extern const __m128i INDEXES[4] = {
  /* fmap (+0*64) [0,4..60] = [0,4..60]      */
  _mm_set_epi8 ( 0x3C, 0x38, 0x34, 0x30, 0x2C, 0x28, 0x24, 0x20,
                 0x1C, 0x18, 0x14, 0x10, 0x0C, 0x08, 0x04, 0x00 ),
  /* fmap (+1*64) [0,4..60] = [64,68..124]   */
  _mm_set_epi8 ( 0x7C, 0x78, 0x74, 0x70, 0x6C, 0x68, 0x64, 0x60,
                 0x5C, 0x58, 0x54, 0x50, 0x4C, 0x48, 0x44, 0x40 ),
  /* fmap (+2*64) [0,4..60] = [128,132..188] */
  _mm_set_epi8 ( 0xBC, 0xB8, 0xB4, 0xB0, 0xAC, 0xA8, 0xA4, 0xA0,
                 0x9C, 0x98, 0x94, 0x90, 0x8C, 0x88, 0x84, 0x80 ),
  /* fmap (+3*64) [0,4..60] = [192,196..252] */
  _mm_set_epi8 ( 0xFC, 0xF8, 0xF4, 0xF0, 0xEC, 0xE8, 0xE4, 0xE0,
                 0xDC, 0xD8, 0xD4, 0xD0, 0xCC, 0xC8, 0xC4, 0xC0 ),
};

/* let as = [ A B ]
 *     -- invert . invert = id
 *     invert A = B
 *     invert B = A
 *     flip = fmap invert
 *     f ps = ps <> flip ps
 *     vs = f (as <> as)
 *     ws = f vs
 *     xs = f ws
 *     ys = f (xs <> xs)
 * in ys
 */
extern const __m128i VIT_MA[64] = {
  /* (0*2) (14-0*2) */
  _mm_set_epi8 (14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0),
  _mm_set_epi8 ( 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14),
  _mm_set_epi8 (14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0),
  _mm_set_epi8 ( 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14),
  _mm_set_epi8 ( 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14),
  _mm_set_epi8 (14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0),
  _mm_set_epi8 ( 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14),
  _mm_set_epi8 (14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0),

  /* (1*2) (14-1*2) */
  _mm_set_epi8 (12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2),
  _mm_set_epi8 ( 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12),
  _mm_set_epi8 (12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2),
  _mm_set_epi8 ( 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12),
  _mm_set_epi8 ( 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12),
  _mm_set_epi8 (12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2),
  _mm_set_epi8 ( 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12),
  _mm_set_epi8 (12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2),

  /* (2*2) (14-2*2) */
  _mm_set_epi8 (10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4),
  _mm_set_epi8 ( 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10),
  _mm_set_epi8 (10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4),
  _mm_set_epi8 ( 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10),
  _mm_set_epi8 ( 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10),
  _mm_set_epi8 (10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4),
  _mm_set_epi8 ( 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10),
  _mm_set_epi8 (10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4),

  /* (3*2) (14-3*2) */
  _mm_set_epi8 ( 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6),
  _mm_set_epi8 ( 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8),
  _mm_set_epi8 ( 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6),
  _mm_set_epi8 ( 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8),
  _mm_set_epi8 ( 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8),
  _mm_set_epi8 ( 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6),
  _mm_set_epi8 ( 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8),
  _mm_set_epi8 ( 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6),

  /* (4*2) (14-4*2) */
  _mm_set_epi8 ( 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8),
  _mm_set_epi8 ( 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6),
  _mm_set_epi8 ( 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8),
  _mm_set_epi8 ( 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6),
  _mm_set_epi8 ( 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6),
  _mm_set_epi8 ( 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8),
  _mm_set_epi8 ( 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6),
  _mm_set_epi8 ( 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8),

  /* (5*2) (14-5*2) */
  _mm_set_epi8 ( 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10),
  _mm_set_epi8 (10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4),
  _mm_set_epi8 ( 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10),
  _mm_set_epi8 (10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4),
  _mm_set_epi8 (10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4),
  _mm_set_epi8 ( 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10),
  _mm_set_epi8 (10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4),
  _mm_set_epi8 ( 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10),

  /* (6*2) (14-6*2) */
  _mm_set_epi8 ( 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12),
  _mm_set_epi8 (12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2),
  _mm_set_epi8 ( 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12),
  _mm_set_epi8 (12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2),
  _mm_set_epi8 (12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2),
  _mm_set_epi8 ( 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12),
  _mm_set_epi8 (12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2),
  _mm_set_epi8 ( 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12),

  /* (7*2) (14-7*2) */
  _mm_set_epi8 ( 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14),
  _mm_set_epi8 (14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0),
  _mm_set_epi8 ( 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14),
  _mm_set_epi8 (14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0),
  _mm_set_epi8 (14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0),
  _mm_set_epi8 ( 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14),
  _mm_set_epi8 (14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0),
  _mm_set_epi8 ( 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14),
};

/* let as = [ A B ]
 *     -- invert . invert = id
 *     invert A = B
 *     invert B = A
 *     flip = fmap invert
 *     f ps = ps <> flip ps
 *     vs = f as
 *     ws = f vs
 *     xs = f ws
 *     ys = xs <> xs <> xs <> xs
 * in ys
 */
extern const __m128i VIT_MB[64] = {
  /* (0*2) (14-0*2) */
  _mm_set_epi8 ( 0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0),
  _mm_set_epi8 (14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14),
  _mm_set_epi8 ( 0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0),
  _mm_set_epi8 (14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14),
  _mm_set_epi8 ( 0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0),
  _mm_set_epi8 (14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14),
  _mm_set_epi8 ( 0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0),
  _mm_set_epi8 (14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14),

  /* (1*2) (14-1*2) */
  _mm_set_epi8 ( 2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2),
  _mm_set_epi8 (12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12),
  _mm_set_epi8 ( 2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2),
  _mm_set_epi8 (12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12),
  _mm_set_epi8 ( 2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2),
  _mm_set_epi8 (12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12),
  _mm_set_epi8 ( 2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2),
  _mm_set_epi8 (12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12),

  /* (2*2) (14-2*2) */
  _mm_set_epi8 ( 4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4),
  _mm_set_epi8 (10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10),
  _mm_set_epi8 ( 4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4),
  _mm_set_epi8 (10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10),
  _mm_set_epi8 ( 4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4),
  _mm_set_epi8 (10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10),
  _mm_set_epi8 ( 4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4),
  _mm_set_epi8 (10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10),

  /* (3*2) (14-3*2) */
  _mm_set_epi8 ( 6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6),
  _mm_set_epi8 ( 8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8),
  _mm_set_epi8 ( 6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6),
  _mm_set_epi8 ( 8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8),
  _mm_set_epi8 ( 6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6),
  _mm_set_epi8 ( 8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8),
  _mm_set_epi8 ( 6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6),
  _mm_set_epi8 ( 8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8),

  /* (4*2) (14-4*2) */
  _mm_set_epi8 ( 8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8),
  _mm_set_epi8 ( 6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6),
  _mm_set_epi8 ( 8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8),
  _mm_set_epi8 ( 6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6),
  _mm_set_epi8 ( 8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8),
  _mm_set_epi8 ( 6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6),
  _mm_set_epi8 ( 8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8),
  _mm_set_epi8 ( 6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6),

  /* (5*2) (14-5*2) */
  _mm_set_epi8 (10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10),
  _mm_set_epi8 ( 4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4),
  _mm_set_epi8 (10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10),
  _mm_set_epi8 ( 4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4),
  _mm_set_epi8 (10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10),
  _mm_set_epi8 ( 4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4),
  _mm_set_epi8 (10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10),
  _mm_set_epi8 ( 4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4),

  /* (6*2) (14-6*2) */
  _mm_set_epi8 (12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12),
  _mm_set_epi8 ( 2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2),
  _mm_set_epi8 (12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12),
  _mm_set_epi8 ( 2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2),
  _mm_set_epi8 (12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12),
  _mm_set_epi8 ( 2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2),
  _mm_set_epi8 (12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12),
  _mm_set_epi8 ( 2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2),

  /* (7*2) (14-7*2) */
  _mm_set_epi8 (14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14),
  _mm_set_epi8 ( 0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0),
  _mm_set_epi8 (14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14),
  _mm_set_epi8 ( 0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0),
  _mm_set_epi8 (14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14),
  _mm_set_epi8 ( 0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0),
  _mm_set_epi8 (14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14),
  _mm_set_epi8 ( 0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0),
};

#else


extern const vub::data_type ALL_INVERSE_ONE = {
    (0xFE), (0xFE), (0xFE), (0xFE),
    (0xFE), (0xFE), (0xFE), (0xFE),
    (0xFE), (0xFE), (0xFE), (0xFE),
    (0xFE), (0xFE), (0xFE), (0xFE),
};

extern const vub::data_type ALL_ONE = {
		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
	};

extern const vub::data_type ALL_M128 = {
    (0x80), (0x80), (0x80), (0x80),
    (0x80), (0x80), (0x80), (0x80),
    (0x80), (0x80), (0x80), (0x80),
    (0x80), (0x80), (0x80), (0x80),
};

extern const vub::data_type ALL_INIT = {
    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
};

extern const vub::data_type ALL_INIT0 = {
    0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
};


extern A16 const vub::data_type INDEXES [4] = {
		{0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
		 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,},

		{0x40, 0x44, 0x48, 0x4C, 0x50, 0x54, 0x58, 0x5C,
		 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74, 0x78, 0x7C,},

		{(0x80), (0x84), (0x88), (0x8C),
		 (0x90), (0x94), (0x98), (0x9C),
		 (0xA0), (0xA4), (0xA8), (0xAC),
		 (0xB0), (0xB4), (0xB8), (0xBC),},

		{(0xC0), (0xC4), (0xC8), (0xCC),
		 (0xD0), (0xD4), (0xD8), (0xDC),
		 (0xE0), (0xE4), (0xE8), (0xEC),
		 (0xF0), (0xF4), (0xF8), (0xFC),}
	};

extern const vub::data_type VIT_MA[8 * 8] =
{
    { 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14,},
    {14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0,},
    { 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14,},
    {14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0,},
    {14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0,},
    { 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14,},
    {14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0,},
    { 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14,},
    { 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12,},
    {12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2,},
    { 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12,},
    {12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2,},
    {12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2,},
    { 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12,},
    {12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2,},
    { 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12,},
    { 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10,},
    {10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4,},
    { 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10,},
    {10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4,},
    {10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4,},
    { 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10,},
    {10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4,},
    { 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10,},
    { 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8,},
    { 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6,},
    { 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8,},
    { 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6,},
    { 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6,},
    { 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8,},
    { 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6,},
    { 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8,},
    { 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6,},
    { 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8,},
    { 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6,},
    { 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8,},
    { 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8,},
    { 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6,},
    { 6,  8,  6,  8,  8,  6,  8,  6,  8,  6,  8,  6,  6,  8,  6,  8,},
    { 8,  6,  8,  6,  6,  8,  6,  8,  6,  8,  6,  8,  8,  6,  8,  6,},
    {10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4,},
    { 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10,},
    {10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4,},
    { 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10,},
    { 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10,},
    {10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4,},
    { 4, 10,  4, 10, 10,  4, 10,  4, 10,  4, 10,  4,  4, 10,  4, 10,},
    {10,  4, 10,  4,  4, 10,  4, 10,  4, 10,  4, 10, 10,  4, 10,  4,},
    {12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2,},
    { 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12,},
    {12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2,},
    { 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12,},
    { 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12,},
    {12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2,},
    { 2, 12,  2, 12, 12,  2, 12,  2, 12,  2, 12,  2,  2, 12,  2, 12,},
    {12,  2, 12,  2,  2, 12,  2, 12,  2, 12,  2, 12, 12,  2, 12,  2,},
    {14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0,},
    { 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14,},
    {14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0,},
    { 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14,},
    { 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14,},
    {14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0,},
    { 0, 14,  0, 14, 14,  0, 14,  0, 14,  0, 14,  0,  0, 14,  0, 14,},
    {14,  0, 14,  0,  0, 14,  0, 14,  0, 14,  0, 14, 14,  0, 14,  0,},
};

extern const vub::data_type VIT_MB[8 * 8] = {
	 {0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0,},
	{14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14,},
	 {0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0,},
	{14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14,},
	 {0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0,},
	{14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14,},
	 {0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0,},
	{14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14,},
	 {2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2,},
	{12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12,},
	 {2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2,},
	{12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12,},
	 {2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2,},
	{12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12,},
	 {2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2,},
	{12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12,},
	 {4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4,},
	{10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10,},
	 {4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4,},
	{10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10,},
	 {4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4,},
	{10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10,},
	 {4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4,},
	{10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10,},
	 {6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6,},
	 {8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8,},
	 {6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6,},
	 {8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8,},
	 {6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6,},
	 {8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8,},
	 {6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6,},
	 {8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8,},
	 {8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8,},
	 {6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6,},
	 {8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8,},
	 {6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6,},
	 {8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8,},
	 {6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6,},
	 {8,  6,  6,  8,  6,  8,  8,  6,  6,  8,  8,  6,  8,  6,  6,  8,},
	 {6,  8,  8,  6,  8,  6,  6,  8,  8,  6,  6,  8,  6,  8,  8,  6,},
	{10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10,},
	 {4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4,},
	{10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10,},
	 {4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4,},
	{10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10,},
	 {4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4,},
	{10,  4,  4, 10,  4, 10, 10,  4,  4, 10, 10,  4, 10,  4,  4, 10,},
	 {4, 10, 10,  4, 10,  4,  4, 10, 10,  4,  4, 10,  4, 10, 10,  4,},
	{12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12,},
	 {2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2,},
	{12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12,},
	 {2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2,},
	{12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12,},
	 {2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2,},
	{12,  2,  2, 12,  2, 12, 12,  2,  2, 12, 12,  2, 12,  2,  2, 12,},
	 {2, 12, 12,  2, 12,  2,  2, 12, 12,  2,  2, 12,  2, 12, 12,  2,},
	{14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14,},
	 {0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0,},
	{14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14,},
	 {0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0,},
	{14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14,},
	 {0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0,},
	{14,  0,  0, 14,  0, 14, 14,  0,  0, 14, 14,  0, 14,  0,  0, 14,},
	 {0, 14, 14,  0, 14,  0,  0, 14, 14,  0,  0, 14,  0, 14, 14,  0,},
};


#endif

#endif


